/* log.h */

#ifndef __LOG_H__
#define __LOG_H__ 1

#include <stdio.h>
#define BUFFER_SIZE 4096
#define BUFFER_NUM 2

enum {
	LOG_ERROR = 0,
	LOG_WARNING,
	LOG_NOTICE,
	LOG_DEBUG
};

struct buffer{
	char data[BUFFER_SIZE];
	int ready;
	struct buffer *next;
	int id;
};

void log_print(const int level, const char *fmt, ...);
void log_close(void);
int log_init(const char *path);

#ifdef DEBUG

#define pthread_mutex_lock(x)\
do {\
	log_print(LOG_DEBUG, "[%x] pthread_mutex_lock(" #x ")\n", pthread_self());\
	pthread_mutex_lock(x);\
} while(0)

#define pthread_mutex_unlock(x)\
do {\
	pthread_mutex_unlock(x);\
	log_print(LOG_DEBUG, "[%x] pthread_mutex_unlock(" #x ")\n", pthread_self());\
} while(0)

#define pthread_join(x, y)\
do {\
	log_print(LOG_DEBUG, "[%x] pthread_join([%x], " #y ")\n", pthread_self(), x);\
	pthread_join(x, y);\
} while(0)

#define pthread_cancel(x)\
do {\
	log_print(LOG_DEBUG, "[%x] pthread_cancel([%x])\n", pthread_self(), x);\
	pthread_cancel(x);\
} while(0)

#define pthread_cond_signal(x)\
do {\
	log_print(LOG_DEBUG, "[%x] pthread_cond_signal(" #x ")\n", pthread_self());\
	pthread_cond_signal(x);\
} while(0)

#define pthread_cond_wait(x, y)\
do {\
	log_print(LOG_DEBUG, "[%x] entering pthread_cond_wait(" #x ", " #y ")\n",\
	    pthread_self());\
	pthread_cond_wait(x, y);\
	log_print(LOG_DEBUG, "[%x] exiting pthread_cond_wait(" #x ", " #y ")\n",\
	    pthread_self());\
} while(0)

#define pthread_cond_timedwait(x, y, z)\
do {\
	log_print(LOG_DEBUG, "[%x] entering pthread_cond_timedwait(" #x ", " #y ", " #z ")\n",\
	    pthread_self());\
	pthread_cond_timedwait(x, y, z);\
	log_print(LOG_DEBUG, "[%x] exiting pthread_cond_timedwait(" #x ", " #y ", " #z ")\n",\
	    pthread_self());\
} while(0)

#define pthread_exit(x)\
do {\
	log_print(LOG_DEBUG, "[%x] pthread_exit(" #x ")\n", pthread_self());\
	pthread_exit(x);\
} while(0)

#endif /* DEBUG */

#endif /* __LOG_H__ */
